home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / amiga / plotting / gnuplot3.lzh / gnuplot / internal.c < prev    next >
C/C++ Source or Header  |  1991-08-22  |  16KB  |  859 lines

  1. /* GNUPLOT - internal.c */
  2. /*
  3.  * Copyright (C) 1986, 1987, 1990, 1991   Thomas Williams, Colin Kelley
  4.  *
  5.  * Permission to use, copy, and distribute this software and its
  6.  * documentation for any purpose with or without fee is hereby granted, 
  7.  * provided that the above copyright notice appear in all copies and 
  8.  * that both that copyright notice and this permission notice appear 
  9.  * in supporting documentation.
  10.  *
  11.  * Permission to modify the software is granted, but not the right to
  12.  * distribute the modified code.  Modifications are to be distributed 
  13.  * as patches to released version.
  14.  *  
  15.  * This software is provided "as is" without express or implied warranty.
  16.  * 
  17.  *
  18.  * AUTHORS
  19.  * 
  20.  *   Original Software:
  21.  *     Thomas Williams,  Colin Kelley.
  22.  * 
  23.  *   Gnuplot 2.0 additions:
  24.  *       Russell Lang, Dave Kotz, John Campbell.
  25.  *
  26.  *   Gnuplot 3.0 additions:
  27.  *       Gershon Elber and many others.
  28.  * 
  29.  * Send your comments or suggestions to 
  30.  *  pixar!info-gnuplot@sun.com.
  31.  * This is a mailing list; to join it send a note to 
  32.  *  pixar!info-gnuplot-request@sun.com.  
  33.  * Send bug reports to
  34.  *  pixar!bug-gnuplot@sun.com.
  35.  */
  36.  
  37. #include <math.h>
  38. #include <stdio.h>
  39. #include "plot.h"
  40.  
  41. BOOLEAN undefined;
  42.  
  43. char *strcpy();
  44.  
  45. struct value *pop(), *complex(), *integer();
  46. double magnitude(), angle(), real();
  47.  
  48. struct value stack[STACK_DEPTH];
  49.  
  50. int s_p = -1;   /* stack pointer */
  51.  
  52.  
  53. /*
  54.  * System V and MSC 4.0 call this when they wants to print an error message.
  55.  * Don't!
  56.  */
  57. #ifdef MSDOS
  58. #ifdef __TURBOC__
  59. int matherr()    /* Turbo C */
  60. #else
  61. int matherr(x)    /* MSC 5.1 */
  62. struct exception *x;
  63. #endif /* TURBOC */
  64. #else /* not MSDOS */
  65. #ifdef apollo
  66. int matherr(struct exception *x)    /* apollo */
  67. #else /* apollo */
  68. #ifdef AMIGA_LC_5_1
  69. int matherr(x)    /* AMIGA_LC_5_1 */
  70. struct exception *x;
  71. #else    /* Most everyone else (not apollo). */
  72. int matherr()
  73. #endif /* AMIGA_LC_5_1 */
  74. #endif /* apollo */
  75. #endif /* MSDOS */
  76. {
  77.     return (undefined = TRUE);        /* don't print error message */
  78. }
  79.  
  80.  
  81. reset_stack()
  82. {
  83.     s_p = -1;
  84. }
  85.  
  86.  
  87. check_stack()    /* make sure stack's empty */
  88. {
  89.     if (s_p != -1)
  90.         fprintf(stderr,"\nwarning:  internal error--stack not empty!\n");
  91. }
  92.  
  93.  
  94. struct value *pop(x)
  95. struct value *x;
  96. {
  97.     if (s_p  < 0 )
  98.         int_error("stack underflow",NO_CARET);
  99.     *x = stack[s_p--];
  100.     return(x);
  101. }
  102.  
  103.  
  104. push(x)
  105. struct value *x;
  106. {
  107.     if (s_p == STACK_DEPTH - 1)
  108.         int_error("stack overflow",NO_CARET);
  109.     stack[++s_p] = *x;
  110. }
  111.  
  112.  
  113. #define ERR_VAR "undefined variable: "
  114.  
  115. f_push(x)
  116. union argument *x;        /* contains pointer to value to push; */
  117. {
  118. static char err_str[sizeof(ERR_VAR) + MAX_ID_LEN] = ERR_VAR;
  119. struct udvt_entry *udv;
  120.  
  121.     udv = x->udv_arg;
  122.     if (udv->udv_undef) {     /* undefined */
  123.         (void) strcpy(&err_str[sizeof(ERR_VAR) - 1], udv->udv_name);
  124.         int_error(err_str,NO_CARET);
  125.     }
  126.     push(&(udv->udv_value));
  127. }
  128.  
  129.  
  130. f_pushc(x)
  131. union argument *x;
  132. {
  133.     push(&(x->v_arg));
  134. }
  135.  
  136.  
  137. f_pushd1(x)
  138. union argument *x;
  139. {
  140.     push(&(x->udf_arg->dummy_values[0]));
  141. }
  142.  
  143.  
  144. f_pushd2(x)
  145. union argument *x;
  146. {
  147.     push(&(x->udf_arg->dummy_values[1]));
  148. }
  149.  
  150.  
  151. #define ERR_FUN "undefined function: "
  152.  
  153. f_call(x)  /* execute a udf */
  154. union argument *x;
  155. {
  156. static char err_str[sizeof(ERR_FUN) + MAX_ID_LEN] = ERR_FUN;
  157. register struct udft_entry *udf;
  158. struct value save_dummy;
  159.  
  160.     udf = x->udf_arg;
  161.     if (!udf->at) { /* undefined */
  162.         (void) strcpy(&err_str[sizeof(ERR_FUN) - 1],
  163.                 udf->udf_name);
  164.         int_error(err_str,NO_CARET);
  165.     }
  166.     save_dummy = udf->dummy_values[0];
  167.     (void) pop(&(udf->dummy_values[0]));
  168.  
  169.     execute_at(udf->at);
  170.     udf->dummy_values[0] = save_dummy;
  171. }
  172.  
  173. f_call2(x)  /* execute a udf of two variables */
  174. union argument *x;
  175. {
  176. static char err_str[sizeof(ERR_FUN) + MAX_ID_LEN] = ERR_FUN;
  177. register struct udft_entry *udf;
  178. struct value save_dummy0, save_dummy1;
  179.  
  180.     udf = x->udf_arg;
  181.     if (!udf->at) { /* undefined */
  182.         (void) strcpy(&err_str[sizeof(ERR_FUN) - 1],
  183.                 udf->udf_name);
  184.         int_error(err_str,NO_CARET);
  185.     }
  186.     save_dummy1 = udf->dummy_values[1];
  187.     save_dummy0 = udf->dummy_values[0];
  188.     (void) pop(&(udf->dummy_values[1]));
  189.     (void) pop(&(udf->dummy_values[0]));
  190.  
  191.     execute_at(udf->at);
  192.     udf->dummy_values[1] = save_dummy1;
  193.     udf->dummy_values[0] = save_dummy0;
  194. }
  195.  
  196.  
  197. static int_check(v)
  198. struct value *v;
  199. {
  200.     if (v->type != INT)
  201.         int_error("non-integer passed to boolean operator",NO_CARET);
  202. }
  203.  
  204.  
  205. f_lnot()
  206. {
  207. struct value a;
  208.     int_check(pop(&a));
  209.     push(integer(&a,!a.v.int_val) );
  210. }
  211.  
  212.  
  213. f_bnot()
  214. {
  215. struct value a;
  216.     int_check(pop(&a));
  217.     push( integer(&a,~a.v.int_val) );
  218. }
  219.  
  220.  
  221. f_bool()
  222. {            /* converts top-of-stack to boolean */
  223.     int_check(&top_of_stack);
  224.     top_of_stack.v.int_val = !!top_of_stack.v.int_val;
  225. }
  226.  
  227.  
  228. f_lor()
  229. {
  230. struct value a,b;
  231.     int_check(pop(&b));
  232.     int_check(pop(&a));
  233.     push( integer(&a,a.v.int_val || b.v.int_val) );
  234. }
  235.  
  236. f_land()
  237. {
  238. struct value a,b;
  239.     int_check(pop(&b));
  240.     int_check(pop(&a));
  241.     push( integer(&a,a.v.int_val && b.v.int_val) );
  242. }
  243.  
  244.  
  245. f_bor()
  246. {
  247. struct value a,b;
  248.     int_check(pop(&b));
  249.     int_check(pop(&a));
  250.     push( integer(&a,a.v.int_val | b.v.int_val) );
  251. }
  252.  
  253.  
  254. f_xor()
  255. {
  256. struct value a,b;
  257.     int_check(pop(&b));
  258.     int_check(pop(&a));
  259.     push( integer(&a,a.v.int_val ^ b.v.int_val) );
  260. }
  261.  
  262.  
  263. f_band()
  264. {
  265. struct value a,b;
  266.     int_check(pop(&b));
  267.     int_check(pop(&a));
  268.     push( integer(&a,a.v.int_val & b.v.int_val) );
  269. }
  270.  
  271.  
  272. f_uminus()
  273. {
  274. struct value a;
  275.     (void) pop(&a);
  276.     switch(a.type) {
  277.         case INT:
  278.             a.v.int_val = -a.v.int_val;
  279.             break;
  280.         case CMPLX:
  281.             a.v.cmplx_val.real =
  282.                 -a.v.cmplx_val.real;
  283.             a.v.cmplx_val.imag =
  284.                 -a.v.cmplx_val.imag;
  285.     }
  286.     push(&a);
  287. }
  288.  
  289.  
  290. f_eq() /* note: floating point equality is rare because of roundoff error! */
  291. {
  292. struct value a, b;
  293.     register int result;
  294.     (void) pop(&b);
  295.     (void) pop(&a);
  296.     switch(a.type) {
  297.         case INT:
  298.             switch (b.type) {
  299.                 case INT:
  300.                     result = (a.v.int_val ==
  301.                         b.v.int_val);
  302.                     break;
  303.                 case CMPLX:
  304.                     result = (a.v.int_val ==
  305.                         b.v.cmplx_val.real &&
  306.                        b.v.cmplx_val.imag == 0.0);
  307.             }
  308.             break;
  309.         case CMPLX:
  310.             switch (b.type) {
  311.                 case INT:
  312.                     result = (b.v.int_val == a.v.cmplx_val.real &&
  313.                        a.v.cmplx_val.imag == 0.0);
  314.                     break;
  315.                 case CMPLX:
  316.                     result = (a.v.cmplx_val.real==
  317.                         b.v.cmplx_val.real &&
  318.                         a.v.cmplx_val.imag==
  319.                         b.v.cmplx_val.imag);
  320.             }
  321.     }
  322.     push(integer(&a,result));
  323. }
  324.  
  325.  
  326. f_ne()
  327. {
  328. struct value a, b;
  329.     register int result;
  330.     (void) pop(&b);
  331.     (void) pop(&a);
  332.     switch(a.type) {
  333.         case INT:
  334.             switch (b.type) {
  335.                 case INT:
  336.                     result = (a.v.int_val !=
  337.                         b.v.int_val);
  338.                     break;
  339.                 case CMPLX:
  340.                     result = (a.v.int_val !=
  341.                         b.v.cmplx_val.real ||
  342.                        b.v.cmplx_val.imag != 0.0);
  343.             }
  344.             break;
  345.         case CMPLX:
  346.             switch (b.type) {
  347.                 case INT:
  348.                     result = (b.v.int_val !=
  349.                         a.v.cmplx_val.real ||
  350.                        a.v.cmplx_val.imag != 0.0);
  351.                     break;
  352.                 case CMPLX:
  353.                     result = (a.v.cmplx_val.real !=
  354.                         b.v.cmplx_val.real ||
  355.                         a.v.cmplx_val.imag !=
  356.                         b.v.cmplx_val.imag);
  357.             }
  358.     }
  359.     push(integer(&a,result));
  360. }
  361.  
  362.  
  363. f_gt()
  364. {
  365. struct value a, b;
  366.     register int result;
  367.     (void) pop(&b);
  368.     (void) pop(&a);
  369.     switch(a.type) {
  370.         case INT:
  371.             switch (b.type) {
  372.                 case INT:
  373.                     result = (a.v.int_val >
  374.                         b.v.int_val);
  375.                     break;
  376.                 case CMPLX:
  377.                     result = (a.v.int_val >
  378.                         b.v.cmplx_val.real);
  379.             }
  380.             break;
  381.         case CMPLX:
  382.             switch (b.type) {
  383.                 case INT:
  384.                     result = (a.v.cmplx_val.real >
  385.                         b.v.int_val);
  386.                     break;
  387.                 case CMPLX:
  388.                     result = (a.v.cmplx_val.real >
  389.                         b.v.cmplx_val.real);
  390.             }
  391.     }
  392.     push(integer(&a,result));
  393. }
  394.  
  395.  
  396. f_lt()
  397. {
  398. struct value a, b;
  399.     register int result;
  400.     (void) pop(&b);
  401.     (void) pop(&a);
  402.     switch(a.type) {
  403.         case INT:
  404.             switch (b.type) {
  405.                 case INT:
  406.                     result = (a.v.int_val <
  407.                         b.v.int_val);
  408.                     break;
  409.                 case CMPLX:
  410.                     result = (a.v.int_val <
  411.                         b.v.cmplx_val.real);
  412.             }
  413.             break;
  414.         case CMPLX:
  415.             switch (b.type) {
  416.                 case INT:
  417.                     result = (a.v.cmplx_val.real <
  418.                         b.v.int_val);
  419.                     break;
  420.                 case CMPLX:
  421.                     result = (a.v.cmplx_val.real <
  422.                         b.v.cmplx_val.real);
  423.             }
  424.     }
  425.     push(integer(&a,result));
  426. }
  427.  
  428.  
  429. f_ge()
  430. {
  431. struct value a, b;
  432.     register int result;
  433.     (void) pop(&b);
  434.     (void) pop(&a);
  435.     switch(a.type) {
  436.         case INT:
  437.             switch (b.type) {
  438.                 case INT:
  439.                     result = (a.v.int_val >=
  440.                         b.v.int_val);
  441.                     break;
  442.                 case CMPLX:
  443.                     result = (a.v.int_val >=
  444.                         b.v.cmplx_val.real);
  445.             }
  446.             break;
  447.         case CMPLX:
  448.             switch (b.type) {
  449.                 case INT:
  450.                     result = (a.v.cmplx_val.real >=
  451.                         b.v.int_val);
  452.                     break;
  453.                 case CMPLX:
  454.                     result = (a.v.cmplx_val.real >=
  455.                         b.v.cmplx_val.real);
  456.             }
  457.     }
  458.     push(integer(&a,result));
  459. }
  460.  
  461.  
  462. f_le()
  463. {
  464. struct value a, b;
  465.     register int result;
  466.     (void) pop(&b);
  467.     (void) pop(&a);
  468.     switch(a.type) {
  469.         case INT:
  470.             switch (b.type) {
  471.                 case INT:
  472.                     result = (a.v.int_val <=
  473.                         b.v.int_val);
  474.                     break;
  475.                 case CMPLX:
  476.                     result = (a.v.int_val <=
  477.                         b.v.cmplx_val.real);
  478.             }
  479.             break;
  480.         case CMPLX:
  481.             switch (b.type) {
  482.                 case INT:
  483.                     result = (a.v.cmplx_val.real <=
  484.                         b.v.int_val);
  485.                     break;
  486.                 case CMPLX:
  487.                     result = (a.v.cmplx_val.real <=
  488.                         b.v.cmplx_val.real);
  489.             }
  490.     }
  491.     push(integer(&a,result));
  492. }
  493.  
  494.  
  495. f_plus()
  496. {
  497. struct value a, b, result;
  498.     (void) pop(&b);
  499.     (void) pop(&a);
  500.     switch(a.type) {
  501.         case INT:
  502.             switch (b.type) {
  503.                 case INT:
  504.                     (void) integer(&result,a.v.int_val +
  505.                         b.v.int_val);
  506.                     break;
  507.                 case CMPLX:
  508.                     (void) complex(&result,a.v.int_val +
  509.                         b.v.cmplx_val.real,
  510.                        b.v.cmplx_val.imag);
  511.             }
  512.             break;
  513.         case CMPLX:
  514.             switch (b.type) {
  515.                 case INT:
  516.                     (void) complex(&result,b.v.int_val +
  517.                         a.v.cmplx_val.real,
  518.                        a.v.cmplx_val.imag);
  519.                     break;
  520.                 case CMPLX:
  521.                     (void) complex(&result,a.v.cmplx_val.real+
  522.                         b.v.cmplx_val.real,
  523.                         a.v.cmplx_val.imag+
  524.                         b.v.cmplx_val.imag);
  525.             }
  526.     }
  527.     push(&result);
  528. }
  529.  
  530.  
  531. f_minus()
  532. {
  533. struct value a, b, result;
  534.     (void) pop(&b);
  535.     (void) pop(&a);        /* now do a - b */
  536.     switch(a.type) {
  537.         case INT:
  538.             switch (b.type) {
  539.                 case INT:
  540.                     (void) integer(&result,a.v.int_val -
  541.                         b.v.int_val);
  542.                     break;
  543.                 case CMPLX:
  544.                     (void) complex(&result,a.v.int_val -
  545.                         b.v.cmplx_val.real,
  546.                        -b.v.cmplx_val.imag);
  547.             }
  548.             break;
  549.         case CMPLX:
  550.             switch (b.type) {
  551.                 case INT:
  552.                     (void) complex(&result,a.v.cmplx_val.real -
  553.                         b.v.int_val,
  554.                         a.v.cmplx_val.imag);
  555.                     break;
  556.                 case CMPLX:
  557.                     (void) complex(&result,a.v.cmplx_val.real-
  558.                         b.v.cmplx_val.real,
  559.                         a.v.cmplx_val.imag-
  560.                         b.v.cmplx_val.imag);
  561.             }
  562.     }
  563.     push(&result);
  564. }
  565.  
  566.  
  567. f_mult()
  568. {
  569. struct value a, b, result;
  570.     (void) pop(&b);
  571.     (void) pop(&a);    /* now do a*b */
  572.  
  573.     switch(a.type) {
  574.         case INT:
  575.             switch (b.type) {
  576.                 case INT:
  577.                     (void) integer(&result,a.v.int_val *
  578.                         b.v.int_val);
  579.                     break;
  580.                 case CMPLX:
  581.                     (void) complex(&result,a.v.int_val *
  582.                         b.v.cmplx_val.real,
  583.                         a.v.int_val *
  584.                         b.v.cmplx_val.imag);
  585.             }
  586.             break;
  587.         case CMPLX:
  588.             switch (b.type) {
  589.                 case INT:
  590.                     (void) complex(&result,b.v.int_val *
  591.                         a.v.cmplx_val.real,
  592.                         b.v.int_val *
  593.                         a.v.cmplx_val.imag);
  594.                     break;
  595.                 case CMPLX:
  596.                     (void) complex(&result,a.v.cmplx_val.real*
  597.                         b.v.cmplx_val.real-
  598.                         a.v.cmplx_val.imag*
  599.                         b.v.cmplx_val.imag,
  600.                         a.v.cmplx_val.real*
  601.                         b.v.cmplx_val.imag+
  602.                         a.v.cmplx_val.imag*
  603.                         b.v.cmplx_val.real);
  604.             }
  605.     }
  606.     push(&result);
  607. }
  608.  
  609.  
  610. f_div()
  611. {
  612. struct value a, b, result;
  613. register double square;
  614.     (void) pop(&b);
  615.     (void) pop(&a);    /* now do a/b */
  616.  
  617.     switch(a.type) {
  618.         case INT:
  619.             switch (b.type) {
  620.                 case INT:
  621.                     if (b.v.int_val)
  622.                       (void) integer(&result,a.v.int_val /
  623.                         b.v.int_val);
  624.                     else {
  625.                       (void) integer(&result,0);
  626.                       undefined = TRUE;
  627.                     }
  628.                     break;
  629.                 case CMPLX:
  630.                     square = b.v.cmplx_val.real*
  631.                         b.v.cmplx_val.real +
  632.                         b.v.cmplx_val.imag*
  633.                         b.v.cmplx_val.imag;
  634.                     if (square)
  635.                         (void) complex(&result,a.v.int_val*
  636.                         b.v.cmplx_val.real/square,
  637.                         -a.v.int_val*
  638.                         b.v.cmplx_val.imag/square);
  639.                     else {
  640.                         (void) complex(&result,0.0,0.0);
  641.                         undefined = TRUE;
  642.                     }
  643.             }
  644.             break;
  645.         case CMPLX:
  646.             switch (b.type) {
  647.                 case INT:
  648.                     if (b.v.int_val)
  649.                       
  650.                       (void) complex(&result,a.v.cmplx_val.real/
  651.                         b.v.int_val,
  652.                         a.v.cmplx_val.imag/
  653.                         b.v.int_val);
  654.                     else {
  655.                         (void) complex(&result,0.0,0.0);
  656.                         undefined = TRUE;
  657.                     }
  658.                     break;
  659.                 case CMPLX:
  660.                     square = b.v.cmplx_val.real*
  661.                         b.v.cmplx_val.real +
  662.                         b.v.cmplx_val.imag*
  663.                         b.v.cmplx_val.imag;
  664.                     if (square)
  665.                     (void) complex(&result,(a.v.cmplx_val.real*
  666.                         b.v.cmplx_val.real+
  667.                         a.v.cmplx_val.imag*
  668.                         b.v.cmplx_val.imag)/square,
  669.                         (a.v.cmplx_val.imag*
  670.                         b.v.cmplx_val.real-
  671.                         a.v.cmplx_val.real*
  672.                         b.v.cmplx_val.imag)/
  673.                             square);
  674.                     else {
  675.                         (void) complex(&result,0.0,0.0);
  676.                         undefined = TRUE;
  677.                     }
  678.             }
  679.     }
  680.     push(&result);
  681. }
  682.  
  683.  
  684. f_mod()
  685. {
  686. struct value a, b;
  687.     (void) pop(&b);
  688.     (void) pop(&a);    /* now do a%b */
  689.  
  690.     if (a.type != INT || b.type != INT)
  691.         int_error("can only mod ints",NO_CARET);
  692.     if (b.v.int_val)
  693.         push(integer(&a,a.v.int_val % b.v.int_val));
  694.     else {
  695.         push(integer(&a,0));
  696.         undefined = TRUE;
  697.     }
  698. }
  699.  
  700.  
  701. f_power()
  702. {
  703. struct value a, b, result;
  704. register int i, t, count;
  705. register double mag, ang;
  706.     (void) pop(&b);
  707.     (void) pop(&a);    /* now find a**b */
  708.  
  709.     switch(a.type) {
  710.         case INT:
  711.             switch (b.type) {
  712.                 case INT:
  713.                     count = abs(b.v.int_val);
  714.                     t = 1;
  715.                     for(i = 0; i < count; i++)
  716.                         t *= a.v.int_val;
  717.                     if (b.v.int_val >= 0)
  718.                         (void) integer(&result,t);
  719.                     else
  720.                       if (t != 0)
  721.                         (void) complex(&result,1.0/t,0.0);
  722.                       else {
  723.                          undefined = TRUE;
  724.                          (void) complex(&result, 0.0, 0.0);
  725.                       }
  726.                     break;
  727.                 case CMPLX:
  728.                     mag =
  729.                       pow(magnitude(&a),fabs(b.v.cmplx_val.real));
  730.                     if (b.v.cmplx_val.real < 0.0)
  731.                       if (mag != 0.0)
  732.                         mag = 1.0/mag;
  733.                       else 
  734.                         undefined = TRUE;
  735.                     mag *= exp(-b.v.cmplx_val.imag*angle(&a));
  736.                     ang = b.v.cmplx_val.real*angle(&a) +
  737.                           b.v.cmplx_val.imag*log(magnitude(&a));
  738.                     (void) complex(&result,mag*cos(ang),
  739.                         mag*sin(ang));
  740.             }
  741.             break;
  742.         case CMPLX:
  743.             switch (b.type) {
  744.                 case INT:
  745.                     if (a.v.cmplx_val.imag == 0.0) {
  746.                         mag = pow(a.v.cmplx_val.real,(double)abs(b.v.int_val));
  747.                         if (b.v.int_val < 0)
  748.                           if (mag != 0.0)
  749.                             mag = 1.0/mag;
  750.                           else 
  751.                             undefined = TRUE;
  752.                         (void) complex(&result,mag,0.0);
  753.                     }
  754.                     else {
  755.                         /* not so good, but...! */
  756.                         mag = pow(magnitude(&a),(double)abs(b.v.int_val));
  757.                         if (b.v.int_val < 0)
  758.                           if (mag != 0.0)
  759.                             mag = 1.0/mag;
  760.                           else 
  761.                             undefined = TRUE;
  762.                         ang = angle(&a)*b.v.int_val;
  763.                         (void) complex(&result,mag*cos(ang),
  764.                             mag*sin(ang));
  765.                     }
  766.                     break;
  767.                 case CMPLX:
  768.                     mag = pow(magnitude(&a),fabs(b.v.cmplx_val.real));
  769.                     if (b.v.cmplx_val.real < 0.0)
  770.                       if (mag != 0.0)
  771.                         mag = 1.0/mag;
  772.                       else 
  773.                         undefined = TRUE;
  774.                     mag *= exp(-b.v.cmplx_val.imag*angle(&a));
  775.                     ang = b.v.cmplx_val.real*angle(&a) +
  776.                           b.v.cmplx_val.imag*log(magnitude(&a));
  777.                     (void) complex(&result,mag*cos(ang),
  778.                         mag*sin(ang));
  779.             }
  780.     }
  781.     push(&result);
  782. }
  783.  
  784.  
  785. f_factorial()
  786. {
  787. struct value a;
  788. register int i;
  789. register double val;
  790.  
  791.     (void) pop(&a);    /* find a! (factorial) */
  792.  
  793.     switch (a.type) {
  794.         case INT:
  795.             val = 1.0;
  796.             for (i = a.v.int_val; i > 1; i--)  /*fpe's should catch overflows*/
  797.                 val *= i;
  798.             break;
  799.         default:
  800.             int_error("factorial (!) argument must be an integer",
  801.             NO_CARET);
  802.         }
  803.  
  804.     push(complex(&a,val,0.0));
  805.             
  806. }
  807.  
  808.  
  809. int
  810. f_jump(x)
  811. union argument *x;
  812. {
  813.     return(x->j_arg);
  814. }
  815.  
  816.  
  817. int
  818. f_jumpz(x)
  819. union argument *x;
  820. {
  821. struct value a;
  822.     int_check(&top_of_stack);
  823.     if (top_of_stack.v.int_val) {    /* non-zero */
  824.         (void) pop(&a);
  825.         return 1;                /* no jump */
  826.     }
  827.     else
  828.         return(x->j_arg);        /* leave the argument on TOS */
  829. }
  830.  
  831.  
  832. int
  833. f_jumpnz(x)
  834. union argument *x;
  835. {
  836. struct value a;
  837.     int_check(&top_of_stack);
  838.     if (top_of_stack.v.int_val)    /* non-zero */
  839.         return(x->j_arg);        /* leave the argument on TOS */
  840.     else {
  841.         (void) pop(&a);
  842.         return 1;                /* no jump */
  843.     }
  844. }
  845.  
  846.  
  847. int
  848. f_jtern(x)
  849. union argument *x;
  850. {
  851. struct value a;
  852.  
  853.     int_check(pop(&a));
  854.     if (a.v.int_val)
  855.         return(1);                /* no jump; fall through to TRUE code */
  856.     else
  857.         return(x->j_arg);        /* go jump to FALSE code */
  858. }
  859.